﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using WatiN.Core;
using WatiN.Core.Native.Windows;
using WebAutomation.Browsers;

namespace WebAutomation
{
    public class AssertCommand : CommandBase
    {
        public AssertCommand(WebBrowserObject browserObject)
        {
            this.Initialize(browserObject);

        }

        public override bool ExecuteCommand(WebBrowserObject browserObject, string[] parameter, string url, string testRepo, string testResultLocation, string dbConnString, ref System.Data.DataSet dataFromDB, ref TestLineResult testLineResult, ref bool stopTest, WebAutoUtils.ITestDataExceptionRules testDataExceptionRules)
        {
            string command = parameter[0];
            try
            {
                testLineResult.LineCommand = command;
                testLineResult.LineParameter = parameter[1];
                if (this.BrowserObject == null)
                {
                    this.BrowserObject = browserObject;
                }
                string value1 = "";
                string value2 = "";
                
                bool isCommandAvailable = false;
                testLineResult.LineSubCommand = command;
                switch(command.ToLower())
                {
                    case "areequal":
                        isCommandAvailable = true;
                        string[] values = ParseAssertValues(parameter[1]);
                        value1 = values[0];
                        value2 = values[1];
                        if (AssertAreEqual(value1,value2))
                        {
                            testLineResult.LineMessage = value1 + " is equal to " + value2;
                            testLineResult.LinePassed = true; 
                        }else
                        {
                            testLineResult.LineMessage = value1 + " does not equal " + value2;
                            testLineResult.LinePassed = false;
                        }
                        break;
                    case "areenotequal":
                        isCommandAvailable = true;
                        string[] valuesNotEqual = ParseAssertValues(parameter[1]);
                        value1 = valuesNotEqual[0];
                        value2 = valuesNotEqual[1];
                        //if (value1.Contains("Variable"))
                        //{
                        //    string tmpvalue1 =TestCommands.GetVariable(value1.Replace("Variable[", "").Replace("]", ""));
                        //    value1 = tmpvalue1;
                        //}
                        //if (value2.Contains("Variable"))
                        //{
                        //    string tmpvalue2 = TestCommands.GetVariable(value2.Replace("Variable[", "").Replace("]", ""));
                        //    value2 = tmpvalue2;
                        //}
                        if (!AssertAreEqual(value1, value2))
                        {
                            testLineResult.LinePassed = true;
                        }
                        else
                        {
                            testLineResult.LineMessage = value1 + " equals " + value2;
                            testLineResult.LinePassed = false;
                        }
                        break;

                    case "pagecontains":
                        isCommandAvailable = true;
                        string pageContainValue = parameter[1].ToLower();
                        string pageHtml = GetPageHTML().ToLower();
                        if (pageHtml.Contains(pageContainValue))
                        {
                            testLineResult.LinePassed = true;
                        }
                        else
                        {
                            testLineResult.LineMessage = "The page does not contain " + pageContainValue+".Try adding a wait command before this command, because the page might not have completely loaded.";
                            testLineResult.LinePassed = false;
                        }
                        break;

                    case "pagenotcontains":
                        isCommandAvailable = true;
                        string pageContainValue2 = parameter[1].ToLower();
                        string pageHtml2 = GetPageHTML().ToLower();
                        if (!pageHtml2.Contains(pageContainValue2))
                        {
                            testLineResult.LinePassed = true;
                        }
                        else
                        {
                            testLineResult.LineMessage = "The page contains " + pageContainValue2 + ".Try adding a wait command before this command, because the page might not have completely loaded.";
                            testLineResult.LinePassed = false;
                        }
                        break;

                    case "fileexists":
                        isCommandAvailable = true;
                        string fileToCheck = "";
                        try
                        {
                            fileToCheck = parameter[1].ToLower();
                            
                        }catch{}
                        if (string.IsNullOrEmpty(fileToCheck))
                        {

                            testLineResult.LineMessage = "You must pass the full file location.";
                            testLineResult.LinePassed = false;
                        }else
                        {
                            if(File.Exists(fileToCheck))
                            {
                                testLineResult.LinePassed = true;
                            }else
                            {
                                testLineResult.LineMessage = "The file("+fileToCheck+") does not exist";
                                testLineResult.LinePassed = false;
                            }
                        }
                        break;

                }
                if(!isCommandAvailable)
                {
                    testLineResult.LineMessage = "The sub-command(" + command + ") does not exist.";
                    testLineResult.LinePassed = false;
                }

  
                
            }
            catch (Exception ex)
            {
                testLineResult.IsFrameworkError = true;
                testLineResult.LineMessage = "Error." + ex.Message + "." + ex.StackTrace;
                testLineResult.LinePassed = false;
            }
            return testLineResult.LinePassed;

        }


        public virtual string[] ParseAssertValues(string values)
        {
            string[] returnValue = new string[2];
            string value1 = values.Split(':')[0];
            string value2 = values.Split(':')[1];
            if (value1.Contains("Variable"))
            {
                string tmpvalue1 = TestCommands.GetVariable(value1.Replace("Variable[", "").Replace("]", ""));
                value1 = tmpvalue1;
            }
            if (values.Split(':')[0].Contains("Data"))
            {
                string[] tmpvalue1 = value1.Replace("Data[", "").Replace("]", "").Split(',');
                string dsName = tmpvalue1[0].Replace("\r\n", "");
                int rowNumber = Convert.ToInt32(tmpvalue1[1]);
                int colNumber = Convert.ToInt32(tmpvalue1[2]);
                int recordSetNumber = 0;
                try
                {
                    recordSetNumber = Convert.ToInt32(tmpvalue1[3]);
                }catch{}
                value1 = TestCommands.GetDataVariable(dsName, rowNumber, colNumber, recordSetNumber);
            }
            if (value2.Contains("Variable"))
            {
                string tmpvalue2 = TestCommands.GetVariable(value2.Replace("Variable[", "").Replace("]", ""));
                value2 = tmpvalue2;
            }
            if (values.Split(':')[1].Contains("Data"))
            {
                string[] tmpvalue1 = value2.Replace("Data[", "").Replace("]", "").Split(',');
                string dsName = tmpvalue1[0].Replace("\r\n", "");
                int rowNumber = Convert.ToInt32(tmpvalue1[1]);
                int colNumber = Convert.ToInt32(tmpvalue1[2]);
                int recordSetNumber = 0;
                try
                {
                    recordSetNumber = Convert.ToInt32(tmpvalue1[3]);
                }
                catch { }
                value2 = TestCommands.GetDataVariable(dsName, rowNumber, colNumber, recordSetNumber);
            }
            returnValue[0] = value1;
            returnValue[1] = value2;
            return returnValue;

        }

        public virtual bool AssertAreEqual(string value1,string value2)
        {
            return (value1 == value2);
        }

        public virtual string GetPageHTML()
        {
            string returnValue = "";
            try
            {
                if (this.BrowserObject.Frames().Count > 0)
                {
                    returnValue = _getPageIframeHTML(this.BrowserObject);
                }
                else
                {
                    returnValue = this.BrowserObject.Html();
                }
            }catch(UnauthorizedAccessException ex)
            {
                
            }

            return returnValue;
        }

        private string _getPageIframeHTML(WebBrowserObject browserObject)
        {
            string returnValue = "";
            if (browserObject.Frames().Count > 0)
            {
                for (int i = 0; i <= browserObject.Frames().Count - 1; i++)
                {
                    browserObject.WaitForCompleteIFrame(i,5000);
                    returnValue = browserObject.HtmlIFrame(i);
                }

            }
            return returnValue;
        }
    }
}
